从这一篇开始,我们进入 AI 编程的深水区——AI Agent。如果说前面的 AI 工具是”问一句答一句”,Agent 则是能自主规划、调用工具、完成任务的智能体。
一、什么是 AI Agent
AI Agent 是指能够自主感知环境、制定计划、执行行动的 AI 系统。和前面介绍的 AI 工具最大的区别是:它是主动的,而不是被动的。
| 能力 |
普通 LLM |
AI Agent |
| 交互方式 |
一问一答 |
多轮自主决策 |
| 工具使用 |
无 |
调用 API、执行代码、读写文件 |
| 规划 |
无 |
分解复杂任务、按步骤执行 |
| 反馈循环 |
无 |
观察结果 → 调整策略 |
| 记忆 |
无(仅当前对话) |
可存取长期记忆 |
二、ReAct 模式——思考-行动-观察
Agent 的核心运行模式叫做 ReAct(Reasoning + Acting)。每一次循环都是”思考→行动→观察”的迭代:
1 2 3 4 5 6 7 8 9
| 用户:帮我查北京明天的天气,定个闹钟提醒带伞
Agent 思考:需要查天气,根据结果决定是否设置提醒 Agent 行动:调用 get_weather(beijing, tomorrow) 环境反馈:{"condition": "rain", "temp": 22} Agent 观察:明天下雨,需要带伞 Agent 行动:set_reminder("带伞", "2025-06-09 08:00") 环境反馈:{"success": true} Agent 回答:已查天气(明天下雨,22°C)并设置了明早 8 点带伞提醒。
|
这个过程不是预设的脚本——每一步的”思考”都是 LLM 实时推理的结果,因此 Agent 能处理从未见过的场景。
ReAct 的 Prompt 模板
如果你手动实现一个简单的 Agent,核心 Prompt 长这样:
1 2 3 4 5 6 7 8 9 10 11 12
| 你是一个智能助手,可以通过调用工具完成任务。 每轮请按以下格式输出:
思考:分析当前状态,决定下一步做什么 行动:{"tool": "工具名", "args": {...}}
当任务完成时,输出: 最终答案:...
可用工具: - get_weather(city, date): 获取天气 - set_reminder(text, time): 设置提醒
|
三、Function Calling——LLM 调用工具的标准接口
3.1 定义工具
要实现 Agent,先定义 LLM 可调用的工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| tools = [{ "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的天气信息", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名,如 '北京'"}, "date": {"type": "string", "description": "日期,格式 YYYY-MM-DD"} }, "required": ["city", "date"] } } }]
|
3.2 Agent 运行循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import json import openai
def agent_loop(user_input: str, max_steps: int = 10): messages = [{"role": "user", "content": user_input}] for step in range(max_steps): response = openai.chat.completions.create( model="deepseek-chat", messages=messages, tools=tools ) msg = response.choices[0].message messages.append(msg) if not msg.tool_calls: return msg.content for tool_call in msg.tool_calls: func_name = tool_call.function.name func_args = json.loads(tool_call.function.arguments) result = execute_tool(func_name, func_args) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result, ensure_ascii=False) }) return "达到最大步数限制,任务可能未完成"
|
3.3 执行工具
1 2 3 4 5 6 7 8 9
| def execute_tool(name: str, args: dict): if name == "get_weather": return {"condition": "rain", "temp": 22, "humidity": 80} elif name == "set_reminder": return {"success": True, "id": "remind_001"} else: return {"error": f"未知工具: {name}"}
|
四、Agent 实战:代码分析助手
构建一个能分析 GitHub 项目的 Agent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| tools = [ { "name": "read_file", "description": "读取项目文件内容", "parameters": { "type": "object", "properties": { "path": {"type": "string"} }, "required": ["path"] } }, { "name": "list_directory", "description": "列出目录中的文件", "parameters": { "type": "object", "properties": { "path": {"type": "string"} }, "required": ["path"] } }, { "name": "search_code", "description": "在项目中搜索代码", "parameters": { "type": "object", "properties": { "pattern": {"type": "string"}, "path": {"type": "string"} }, "required": ["pattern"] } } ]
|
用户问”这个项目的依赖注入是怎么配置的?”,Agent 会自动:
list_directory("src") → 找到项目结构
read_file("src/di/container.ts") → 读取依赖配置
search_code("Injectable") → 搜索装饰器使用
- 综合分析后给出完整答案
五、安全边界
Agent 的自主性越强,安全风险就越大:
| 风险 |
防护措施 |
代码实现 |
| 工具滥用 |
设置 max_steps 上限 |
for step in range(10) |
| 权限过大 |
沙箱环境 + 白名单 |
限制可读写的目录 |
| 成本失控 |
Token 预算上限 |
每次调用后累计 Token 用量 |
| 信息泄露 |
敏感信息过滤 |
工具输入输出过滤 |
| 无限循环 |
超时退出机制 |
timeout = 60s |
1 2 3 4 5 6 7 8 9 10
| class SafeAgent: def __init__(self): self.max_steps = 10 self.max_tokens = 50000 self.token_used = 0 self.allowed_dirs = ["/project/src"] def check_permission(self, path: str) -> bool: return any(path.startswith(d) for d in self.allowed_dirs)
|
六、Agent 应用场景决策树
用决策树判断是否需要使用 Agent:
1 2 3 4 5 6 7
| 这个任务是否需要 API 调用或代码执行? ├── 否 → 用普通 Chat 即可 └── 是 → 任务是否需要多步规划和条件判断? ├── 否 → 用 Function Calling 简单调用 └── 是 → 任务是否需要多个专用角色协作? ├── 否 → 用单 Agent(ReAct 模式) └── 是 → 用多 Agent 框架(CrewAI/LangGraph)
|
6.1 不适用 Agent 的场景
- 单次简单查询:查个天气、问个定义 → Chat 就够了
- 纯信息整理:总结文章、翻译 → 不需要工具调用
- 确定性计算:1+1=2 → 直接计算即可
- 模板化生成:每周周报格式固定 → 用脚本而不是 Agent
七、Agent 与 RAG 的协同
Agent 和 RAG 不是互斥方案,而是互补的:
1 2 3
| Agent(执行者):需要调用工具完成多步任务 ↓ 需要知识 RAG(知识库):为 Agent 提供私有知识支持
|
例如:一个”代码维护 Agent”可以这样协同:
1 2 3 4 5
| 用户:"帮我修复这个 bug" → Agent 理解任务 → RAG 检索同类 bug 的历史修复记录 → Agent 参考历史方案 + 当前代码 → 生成修复 → Agent 调用 git commit 提交修改 → Agent 调用 CI 触发测试验证
|
八、Agent 框架选择
| 框架 |
语言 |
特点 |
适合场景 |
学习曲线 |
| LangChain |
Python |
生态丰富,文档齐全 |
快速原型 |
中等 |
| LangGraph |
Python |
有状态工作流,循环控制 |
复杂流程编排 |
较高 |
| CrewAI |
Python |
多 Agent 协作,角色化 |
团队模拟 |
低 |
| AutoGen |
Python |
微软出品,对话式多 Agent |
研究实验 |
中等 |
| OpenCode Agent |
JS/TS |
CLI 集成,文件操作 |
日常开发 |
低 |
学习路线建议:
- 入门:用 OpenAI/Python 手写一个最小 Agent(上面代码)
- 进阶:用 LangChain 快速构建
- 专业:用 LangGraph 构建有状态工作流
本章小结
- Agent 的核心是”思考→行动→观察”的 ReAct 循环
- Function Calling 是 LLM 调用工具的标准接口,几乎所有主流模型都支持
- 手写一个最小 Agent 只需要 30 行代码 + 工具定义
- Agent 的自主性带来效率提升,也带来安全风险——权限控制必不可少
- 框架推荐:手写入门 → LangChain(进阶)→ LangGraph(专业)
- 成本监控在 Agent 场景中比单次 LLM 调用更重要
下一篇看 MCP 协议——让 Agent 和工具之间的通信标准化。